home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-03-04 | 42.2 KB | 1,052 lines |
- Newsgroups: comp.lang.c,comp.answers,news.answers
- Path: bloom-beacon.mit.edu!hookup!news.kei.com!MathWorks.Com!panix!ddsw1!uunet!nwnexus!oneworld!eskimo!scs
- From: scs@eskimo.com (Steve Summit)
- Subject: comp.lang.c Changes to Answers to Frequently Asked Questions (FAQ)
- Message-ID: <1994Mar02.0102.scs.0001@eskimo.com>
- Followup-To: poster
- Sender: scs@eskimo.com (Steve Summit)
- Reply-To: scs@eskimo.com
- X-Archive-Name: C-faq/diff
- Organization: none, at the moment
- Date: Wed, 2 Mar 1994 09:02:32 GMT
- Approved: news-answers-request@MIT.Edu
- Lines: 1036
- Xref: bloom-beacon.mit.edu comp.lang.c:34952 comp.answers:4019 news.answers:15995
-
- Archive-name: C-faq/diff
- Comp-lang-c-archive-name: C-FAQ-list.diff
-
- Descending upon your newsfeed like so many lead balloons is an
- unaccountably major set of updates to the comp.lang.c FAQ list.
- This diff list is about 40K, considerably bigger than the entire
- abridged list. If you appreciate these changes and additions and
- are feeling frivolous, drop a note to summit@ocean.washington.edu
- and let Melanie (the FAQ list widow) know that my zombie-like
- state over the past few days (a *lot* of suggestions and ideas
- had accumulated) was not completely without redeeming value. :-)
-
- I am experimenting with a table of contents (i.e. a separate list
- of the questions only), which many people have been requesting.
- It's nearly 20K by itself (and that's the text from the abridged
- questions), so I'm posting it as a separate article. Let me know
- if it's useful or how it could be made more useful.
-
- Two of the apparently new questions (17.27 and 17.28) may seem
- familiar to those of you with long memories. I had elided them
- at one point, in a vain attempt to hold the list to some
- reasonable size, but since that's now clearly a lost cause, I
- might as well re-enable them. (The sentence claiming that "Older
- copies are obsolete and don't contain much, except the occasional
- typo, that the current list doesn't" now becomes true again.)
-
- I have one important caution for those of you who are in the
- habit of posting or mailing pointers to this FAQ list: many of
- the questions have been renumbered, so it would be a good idea
- not to refer to questions solely by number for at least a few
- months. (The section numbers, however, remain the same.)
-
- (The following context diffs are edited for readability and are
- not suitable for use with patch programs.)
-
- ==========
- < [Last modified November 3, 1993 by scs.]
- ---
- > [Last modified March 1, 1994 by scs.]
- ==========
- > The old HP 3000 series computers use a different addressing
- > scheme for byte addresses than for word addresses; void and char
- > pointers therefore have a different representation than an int
- > (structure, etc.) pointer to the same address would have.
- ==========
- < Due to the "equivalence of arrays and pointers" (see question
- < 2.3), arrays and pointers often seem interchangeable, and in
- ---
- > Due to the so-called equivalence of arrays and pointers (see
- > question 2.3), arrays and pointers often seem interchangeable,
- ==========
- 2.11: How do I write functions which accept 2-dimensional arrays when
- the "width" is not known at compile time?
- ...
- > gcc allows local arrays to be declared having sizes which are
- > specified by a function's arguments, but this is a nonstandard
- > extension.
- ==========
- > 2.13: Since array references decay to pointers, given
- >
- > int array[NROWS][NCOLUMNS];
- >
- > what's the difference between array and &array?
- >
- > A: Under ANSI/ISO Standard C, &array yields a pointer, of type
- > pointer-to-array-of-T, to the entire array (see also question
- > 2.12). Under pre-ANSI C, the & in &array generally elicited a
- > warning, and was generally ignored. Under all C compilers, an
- > unadorned reference to an array yields a pointer, of type
- > pointer-to-T, to the array's first element. (See also question
- > 2.3.)
- ==========
- 2.15: How can I use statically- and dynamically-allocated
- multidimensional arrays interchangeably when passing them to
- functions?
-
- < A: There is no single perfect method. Given the array and f() as
- < declared in question 2.10, f2() as declared in question 2.11,
- < array1, array2, array3, and array4 as declared in 2.13, and a
- ---
- > A: There is no single perfect method. Given a function f1()
- > similar to the f() of question 2.10, the array as declared in
- > question 2.10, f2() as declared in question 2.11, array1,
- > array2, array3, and array4 as declared in question 2.14, and a
- ==========
- < f(array, NROWS, NCOLUMNS);
- < f(array4, nrows, NCOLUMNS);
- ---
- > f1(array, NROWS, NCOLUMNS);
- > f1(array4, nrows, NCOLUMNS);
- ==========
- < f((int (*)[NCOLUMNS])(*array2), nrows, ncolumns);
- < f((int (*)[NCOLUMNS])array3, nrows, ncolumns);
- ---
- > f1((int (*)[NCOLUMNS])(*array2), nrows, ncolumns);
- > f1((int (*)[NCOLUMNS])array3, nrows, ncolumns);
- ==========
- < It must again be noted that passing array to f2() is not
- ---
- > It must again be noted that passing &array[0][0] to f2() is not
- strictly conforming; see question 2.11.
- ==========
- 2.16: Here's a neat trick: if I write
-
- int realarray[10];
- int *array = &realarray[-1];
-
- I can treat "array" as if it were a 1-based array.
-
- < A: Although this technique is attractive (and is used in the book
- < Numerical Recipes in C), it does not conform to the C standards.
- ---
- > A: Although this technique is attractive (and was used in old
- > editions of the book Numerical Recipes in C), it does not
- ==========
- > 2.19: Can I use a void ** pointer to pass a generic pointer to a
- > function by reference?
- >
- > A: Not portably. There is no generic pointer-to-pointer type in C.
- > void * acts as a generic pointer only because conversions are
- > applied automatically when other pointer types are assigned to
- > and from void *'s; these conversions cannot be performed (the
- > correct underlying pointer type is not known) if an attempt is
- > made to indirect upon a void ** value which points at something
- > other than a void *.
- ==========
- char answer[100], *p;
- printf("Type something:\n");
- < fgets(answer, 100, stdin);
- ---
- > fgets(answer, sizeof(answer), stdin);
- ==========
- Note that this example also uses fgets instead of gets (always a
- < good idea; see question 11.5), so that the size of the array can
- < be specified, so that fgets will not overwrite the end of the
- < array if the user types an overly-long line. (Unfortunately for
- ---
- > good idea; see question 11.5), allowing the size of the array to
- > be specified, so that the end of the array will not be
- > overwritten if the user types an overly-long line.
- ==========
- < \n, as gets would.) It would also be possible to use malloc to
- < allocate the answer buffer, and/or to parameterize its size
- < (#define ANSWERSIZE 100).
- ---
- > delete the trailing \n, as gets would.) It would also be
- > possible to use malloc to allocate the answer buffer.
- ==========
- A: Make sure that the memory to which the function returns a
- pointer is correctly allocated. The returned pointer should be
- to a statically-allocated buffer, or to a buffer passed in by
- < the caller, but _not_ to a local array. See also question 17.3.
- ---
- > the caller, but _not_ to a local (auto) array. In other words,
- > never do something like
- >
- > char *f()
- > {
- > char buf[10];
- > /* ... */
- > return buf;
- > }
- >
- > One fix would to to declare the buffer as
- >
- > static char buf[10];
- >
- > See also question 17.5.
- ==========
- > 3.5: Why does some code carefully cast the values returned by malloc
- > to the pointer type being allocated?
- >
- > A: Before ANSI/ISO Standard C introduced the void * generic pointer
- > type, these casts were typically required to silence warnings
- > about assignment between incompatible pointer types.
- ==========
- 3.6: You can't use dynamically-allocated memory after you free it,
- can you?
-
- < A: No. Some early man pages for malloc stated that the contents of
- ---
- > A: No. Some early documentation for malloc stated that the
- contents of freed memory was "left undisturbed;" this ill-
- advised guarantee was never universal and is not required by
- ==========
- > 3.11: Must I free allocated memory before the program exits?
- >
- > A: You shouldn't have to. A real operating system definitively
- > reclaims all memory when a program exits. Nevertheless, some
- > personal computers are said not to reliably recover memory, and
- > all that can be inferred from the ANSI/ISO C Standard is that it
- > is a "quality of implementation issue."
- >
- > References: ANSI Sec. 4.10.3.2 .
- ==========
- 4.1: Why doesn't this code:
-
- a[i] = i++;
-
- work?
-
- A: The subexpression i++ causes a side effect -- it modifies i's
- value -- which leads to undefined behavior if i is also
- < referenced elsewhere in the same expression.
- ---
- > referenced elsewhere in the same expression. (Note that
- > although the language in K&R suggests that the behavior of this
- > expression is unspecified, the ANSI/ISO C Standard makes the
- > stronger statement that it is undefined -- see question 5.23.)
- ==========
- > 4.3: I've experimented with the code
- >
- > int i = 2;
- > i = i++;
- >
- > on several compilers. Some gave i the value 2, some gave 3, but
- > one gave 4. I know the behavior is undefined, but how could it
- > give 4?
- >
- > A: Undefined behavior means _anything_ can happen. See question
- > 5.23.
- ==========
- > 4.4: People keep saying the behavior is undefined, but I just tried
- > it on an ANSI-conforming compiler, and got the results I
- > expected.
- >
- > A: A compiler may do anything it likes when faced with undefined
- > behavior (and, within limits, with implementation-defined and
- > unspecified behavior), including doing what you expect. It's
- > unwise to depend on it, though. See also question 5.18.
- ==========
- > 4.5: Can I use explicit parentheses to force the order of evaluation
- > I want? Even if I don't, doesn't precedence dictate it?
- >
- > A: Operator precedence and explicit parentheses impose only a
- > partial ordering on the evaluation of an expression. Consider
- > the expression
- >
- > f() + g() * h()
- >
- > -- although we know that the multiplication will happen before
- > the addition, there is no telling which of the three functions
- > will be called first.
- ==========
- 4.6: But what about the &&, ||, and comma operators?
- I see code like "if((c = getchar()) == EOF || c == '\n')" ...
-
- A: There is a special exception for those operators, (as well as
- ==========
- 5.2: How can I get a copy of the Standard?
-
- < A: ANSI X3.159 has been officially superseded by ISO 9899.
- < Copies are available from
- ---
- > A: ANSI X3.159 has been officially superseded by ISO 9899. Copies
- > are available in the United States from
- ==========
- > In other countries, contact the appropriate national standards
- > body, or ISO in Geneva at:
- >
- > ISO Sales
- > Case Postale 56
- > CH-1211 Geneve 20
- > Switzerland
- ==========
- > The mistitled _Annotated ANSI C Standard_, with annotations by
- > Herbert Schildt, contains the full text of ISO 9899; it is
- > published by Osborne/McGraw-Hill, ISBN 0-07-881952-0, and sells
- > in the U.S. for approximately $40. (It has been suggested that
- > the price differential between this work and the official
- > standard reflects the value of the annotations.)
- ==========
- A: Two programs, protoize and unprotoize, convert back and forth
- between prototyped and "old style" function definitions and
- declarations. (These programs do _not_ handle full-blown
- translation between "Classic" C and ANSI C.) These programs
- < exist as patches to the FSF GNU C compiler, gcc. Look for the
- < file protoize-1.39.0.5.Z in pub/gnu at prep.ai.mit.edu
- < (18.71.0.38), or at several other FSF archive sites.
- ---
- > were once patches to the FSF GNU C compiler, gcc, but are now
- > part of the main gcc distribution; look in pub/gnu at
- > prep.ai.mit.edu (18.71.0.38), or at several other FSF archive
- > sites.
- ==========
- < The unproto program (/pub/unix/unproto4.shar.Z on
- ---
- > The unproto program (/pub/unix/unproto5.shar.Z on
- ftp.win.tue.nl) is a filter which sits between the preprocessor
- and the next compiler pass, converting most of ANSI C to
- traditional C on-the-fly.
- ==========
- Several prototype generators exist, many as modifications to
- lint. Version 3 of CPROTO was posted to comp.sources.misc in
- < March, 1992. See also question 17.8.
- ---
- > March, 1992. There is another program called "cextract." See
- > also question 17.12.
- ==========
- > 5.5: I don't understand why I can't use const values in initializers
- > and array dimensions, as in
- >
- > const int n = 5;
- > int a[n];
- >
- > A: The const qualifier really means "read-only;" an object so
- > qualified is a normal run-time object which cannot (normally) be
- > assigned to. The value of a const-qualified object is therefore
- > _not_ a constant expression in the full sense of the term. (C
- > is unlike C++ in this regard.) When you need a true compile-
- > time constant, use a preprocessor #define.
- >
- > References: ANSI Sec. 3.4 .
- ==========
- A: You have mixed the new-style prototype declaration
- "extern int func(float);" with the old-style definition
- < "int func(x) float x;". Old C (and ANSI C, in the absence of
- < prototypes, and in variable-length argument lists) "widens"
- < certain arguments when they are passed to functions. floats are
- < promoted to double, and characters and short integers are
- < promoted to ints. (The values are automatically converted back
- ---
- > "int func(x) float x;". It is usually safe to mix the two
- > styles (see question 5.9), but not in this case. Old C (and
- > ANSI C, in the absence of prototypes, and in variable-length
- > argument lists) "widens" certain arguments when they are passed
- > to functions. floats are promoted to double, and characters and
- > short integers are promoted to ints. (For old-style function
- > definitions, the values are automatically converted back to the
- > corresponding narrower types within the body of the called
- > function, if they are declared that way there.)
- ==========
- > 5.9: Can you mix old-style and new-style function syntax?
- >
- > A: Doing so is perfectly legal, as long as you're careful (see
- > especially question 5.8). Note however that old-style syntax is
- > marked as obsolescent, and support for it may be removed some
- > day.
- >
- > References: ANSI Secs. 3.7.1, 3.9.5 .
- ==========
- > Declaring a function as void does not merely silence warnings;
- > it may also result in a different function call/return sequence,
- > incompatible with what the caller (in main's case, the C run-
- > time startup code) expects.
- ==========
- > 5.17: Why are some ANSI/ISO Standard library routines showing up as
- > undefined, even though I've got an ANSI compiler?
- >
- > A: It's not unusual to have a compiler available which accepts ANSI
- > syntax, but not to have ANSI-compatible header files or run-time
- > libraries installed. See also questions 5.16 and 17.2.
- ==========
- > 5.19: Why can't I perform arithmetic on a void * pointer?
- >
- > A: The compiler doesn't know the size of the pointed-to objects.
- > Before performing arithmetic, cast the pointer either to char *
- > or to the type you're trying to manipulate.
- ==========
- 5.20: Is char a[3] = "abc"; legal? What does it mean?
-
- < A: It is legal, though questionably useful. It declares an array
- ---
- > A: It is legal in ANSI C (and perhaps in a few pre-ANSI systems),
- though questionably useful. It declares an array of size three,
- initialized with the three characters 'a', 'b', and 'c', without
- the usual terminating '\0' character; the array is therefore not
- a true C string and cannot be used with strcpy, printf %s, etc.
- ==========
- > 5.22: What does #pragma once mean? I found it in some header files.
- >
- > A: It is an extension implemented by some preprocessors to help
- > make header files idempotent; it is essentially equivalent to
- > the #ifndef trick mentioned in question 6.4.
- ==========
- > 5.23: People seem to make a point of distinguishing between
- > implementation-defined, unspecified, and undefined behavior.
- > What's the difference?
- >
- > A: Briefly: implementation-defined means that an implementation
- > must choose some behavior and document it. Unspecified means
- > that an implementation should choose some behavior, but need not
- > document it. Undefined means that absolutely anything might
- > happen. In no case does the Standard impose requirements; in
- > the first two cases it occasionally suggests (and may require a
- > choice from among) a small set of likely behaviors.
- >
- > If you're interested in writing portable code, you can ignore
- > the distinctions, as you'll want to avoid code that depends on
- > any of the three behaviors.
- >
- > References: ANSI Sec. 1.6, especially the Rationale.
- ==========
- 6.8: I inherited some code which contains far too many #ifdef's for
- my taste. How can I preprocess the code to leave only one
- conditional compilation set, without running it through cpp and
- expanding all of the #include's and #define's as well?
-
- < A: There is a program floating around called unifdef which does
- ---
- > A: There are programs floating around called unifdef, rmifdef, and
- > scpp which do exactly this. (See question 17.12.)
- ==========
- A: One popular trick is to define the macro with a single argument,
- and call it with a double set of parentheses, which appear to
- the preprocessor to indicate a single argument:
-
- #define DEBUG(args) (printf("DEBUG: "), printf args)
-
- if(n != 0) DEBUG(("n is %d\n", n));
-
- The obvious disadvantage is that the caller must always remember
- < to use the extra parentheses. Another solution is to use
- different macros (DEBUG1, DEBUG2, etc.) depending on the number
- < of arguments. (It is often better to use a bona-fide function,
- < which can take a variable number of arguments in a well-defined
- < way. See questions 7.1 and 7.2 below.)
- ---
- The obvious disadvantage is that the caller must always remember
- > to use the extra parentheses. Other solutions are to use
- different macros (DEBUG1, DEBUG2, etc.) depending on the number
- > of arguments, or to play games with commas:
- >
- > #define DEBUG(args) (printf("DEBUG: "), printf(args))
- > #define _ ,
- > DEBUG("i = %d" _ i)
- >
- > It is often better to use a bona-fide function, which can take a
- > variable number of arguments in a well-defined way. See
- > questions 7.1 and 7.2.
- ==========
- A: This information is not available to a portable program. Some
- old systems provided a nonstandard nargs() function, but its use
- was always questionable, since it typically returned the number
- < of words passed, not the number of arguments. (Floating point
- < values and structures are usually passed as several words.)
- ---
- > of words passed, not the number of arguments. (Structures and
- > floating point values are usually passed as several words.)
- ==========
- > 9.6: How can I read/write structs from/to data files?
- >
- > A: It is relatively straightforward to write a struct out using
- > fwrite:
- >
- > fwrite((char *)&somestruct, sizeof(somestruct), 1, fp);
- >
- > and a corresponding fread invocation can read it back in.
- > However, data files so written will _not_ be very portable (see
- > questions 9.11 and 17.3). Note also that on many systems you
- > must use the "b" flag when fopening the files.
- ==========
- 9.7: I came across some code that declared a structure like this:
-
- struct name
- {
- int namelen;
- char name[1];
- };
-
- and then did some tricky allocation to make the name array act
- like it had several elements. Is this legal and/or portable?
-
- A: This technique is popular, although Dennis Ritchie has called it
- < "unwarranted chumminess with the compiler." An ANSI
- < Interpretation Ruling has deemed it not strictly conforming. It
- ---
- A: This technique is popular, although Dennis Ritchie has called it
- > "unwarranted chumminess with the C implementation." An ANSI
- > Interpretation Ruling has deemed it (more precisely, access
- > beyond the declared size of the name field) to be not strictly
- > conforming, although a thorough treatment of the arguments
- > surrounding the legality of the technique is beyond the scope of
- > this list. It seems, however, to be portable to all known
- implementations. (Compilers which check array bounds carefully
- might issue warnings.)
- >
- > To be on the safe side, it may be preferable to declare the
- > variable-size element very large, rather than very small; in the
- > case of the above example:
- >
- > ...
- > char name[MAXSIZE];
- > ...
- >
- > where MAXSIZE is larger than any name which will be stored.
- > (The trick so modified is said to be in conformance with the
- > Standard.)
- >
- References: ANSI Rationale Sec. 3.5.4.2 pp. 54-5.
- ==========
- > 9.13: How can I pass constant values to routines which accept struct
- > arguments?
- >
- > A: C has no way of generating anonymous struct values. You will
- > have to use a temporary struct variable.
- ==========
- A: Some vendors of C products for 64-bit machines support 64-bit
- long ints. Others fear that too much existing code depends on
- sizeof(int) == sizeof(long) == 32 bits, and introduce a new 64-
- < bit long long int type instead.
- ---
- > bit long long (or __longlong) type instead.
- ==========
- < Vendors who feel compelled to introduce a new long long int type
- ---
- > Vendors who feel compelled to introduce a new, longer integral
- type should advertise it as being "at least 64 bits" (which is
- truly new; a type traditional C doesn't have), and not "exactly
- 64 bits."
- ==========
- > 10.6: My compiler is complaining about an invalid redeclaration of a
- > function, but I only define it once and call it once.
- >
- > A: If the first call precedes the definition, the compiler will
- > assume a function returns an int. Non-int functions must be
- > declared before they are called.
- >
- > References: K&R I Sec. 4.2 pp. 70; K&R II Sec. 4.2 p. 72; ANSI
- > Sec. 3.3.2.2 .
- ==========
- > 10.8: What does extern mean in a function declaration?
- >
- > A: It can be used as a stylistic hint to indicate that the
- > function's definition is probably in another source file, but
- > there is no formal difference between
- >
- > extern int f();
- > and
- > int f();
- >
- > References: ANSI Sec. 3.1.2.2 .
- ==========
- > 10.11: What's the auto keyword good for?
- >
- > A: Nothing; it's obsolete.
- ==========
- 11.2: Why doesn't the code scanf("%d", i); work?
-
- < A: You must always pass addresses (in this case, &i) to scanf.
- ---
- > A: scanf needs pointers to the variables it is to fill in; you must
- > call scanf("%d", &i);
- ==========
- 11.3: Why doesn't this code:
-
- double d;
- scanf("%f", &d);
-
- work?
-
- < A: With scanf, use %lf for values of type double, and %f for float.
- ---
- > A: scanf uses %lf for values of type double, and %f for float.
- (Note the discrepancy with printf, which uses %f for both double
- and float, due to C's default argument promotion rules.)
- ==========
- 11.5: Why does everyone say not to use gets()?
-
- A: It cannot be told the size of the buffer it's to read into, so
- < it cannot be prevented from overflowing that buffer.
- ---
- > it cannot be prevented from overflowing that buffer. See
- > question 3.1 for a code fragment illustrating the replacement of
- > gets() with fgets().
- ==========
- 12.2: I'm trying to sort an array of strings with qsort, using strcmp
- as the comparison function, but it's not working.
-
- A: By "array of strings" you probably mean "array of pointers to
- char." The arguments to qsort's comparison function are
- pointers to the objects being sorted, in this case, pointers to
- pointers to char. (strcmp, of course, accepts simple pointers
- to char.)
- ...
- > Beware of the discussion in K&R II Sec. 5.11 pp. 119-20, which
- > is not discussing Standard library qsort.
- ==========
- 12.3: Now I'm trying to sort an array of structures with qsort. My
- comparison routine takes pointers to structures, but the
- compiler complains that the function is of the wrong type for
- qsort. How can I cast the function pointer to shut off the
- warning?
-
- A: The conversions must be in the comparison function, which must
- be declared as accepting "generic pointers" (const void * or
- > char *) as discussed in question 12.2 above. The code might
- > look like
- >
- > int mystructcmp(p1, p2)
- > char *p1, *p2; /* const void * for ANSI C */
- > {
- > struct mystruct *sp1 = (struct mystruct *)p1;
- > struct mystruct *sp2 = (struct mystruct *)p2;
- > /* now compare sp1->whatever and *sp2-> ... */
- > }
- >
- > (If, on the other hand, you're sorting pointers to structures,
- > you'll need indirection, as in question 12.2:
- > sp1 = *(struct mystruct **)p1 .)
- ==========
- Converting a string to a time_t is harder, because of the wide
- < variety of date and time formats which should be parsed.
- < Public-domain routines have been written for performing this
- < function (see, for example, the file partime.c, widely
- < distributed with the RCS package), but they are less likely to
- < become standardized.
- ---
- > variety of date and time formats which should be parsed. Some
- > systems provide a strptime function; another popular routine is
- > partime (widely distributed with the RCS package), but these are
- > less likely to become standardized.
- ==========
- > 12.7: How can I add n days to a date? How can I find the difference
- > between two dates?
- >
- > A: The ANSI/ISO Standard C mktime and difftime functions provide
- > support for both problems. mktime accepts non-normalized dates,
- > so it is straightforward to take a filled in struct tm, add or
- > subtract from the tm_mday field, and call mktime to normalize
- > the year, month, and day fields (and convert to a time_t value).
- > difftime computes the difference, in seconds, between two time_t
- > values; mktime can be used to compute time_t values for two
- > dates to be subtracted. (Note, however, that these solutions
- > only work for dates which can be represented as time_t's.) See
- > also questions 12.6 and 17.28.
- >
- > References: K&R II Sec. B10 p. 256; H&S Secs. 20.4, 20.5
- > pp. 361-362; ANSI Secs. 4.12.2.2, 4.12.2.3 .
- ==========
- > 12.9: How can I get random integers in a certain range?
- >
- > A: The obvious way,
- >
- > rand() % N
- >
- > (where N is of course the range) is poor, because the low-order
- > bits of many random number generators are distressingly non-
- > random. (See question 12.11.) A better method is something
- > like
- >
- > (int)((double)rand() / ((double)RAND_MAX + 1) * N)
- >
- > If you're worried about using floating point, you could try
- >
- > rand() / (RAND_MAX / N + 1)
- >
- > Both methods obviously require knowing RAND_MAX (which ANSI
- > defines in <stdlib.h>), and assume that N is much less than
- > RAND_MAX.
- ==========
- > 12.13: I keep getting errors due to library routines being undefined,
- > but I'm #including all the right header files.
- >
- > A: In some cases (especially if the routines are nonstandard) you
- > may have to explicitly ask for the correct libraries to be
- > searched when you link the program. See also question 15.2.
- ==========
- > 12.14: I'm still getting errors due to library routines being
- > undefined, even though I'm using -l to request the libraries
- > while linking.
- >
- > A: Many linkers make one pass over the list of object files and
- > libraries you specify, and extract from libraries only those
- > modules which satisfy references which have so far come up as
- > undefined. Therefore, the order in which libraries are listed
- > with respect to object files (and each other) is significant;
- > usually, you want to search the libraries last (i.e., under
- > Unix, put any -l switches towards the end of the command line).
- ==========
- > 12.15: I need some code to do regular expression matching.
- >
- > A: Look for the regexp library (supplied with many Unix systems),
- > or get Henry Spencer's regexp package from cs.toronto.edu in
- > pub/regexp.shar.Z (see also question 17.12).
- ==========
- > 12.16: How can I split up a command line into argc and argv, like the
- > shell does?
- >
- > A: Most systems have a routine called strtok.
- >
- > References: ANSI Sec. 4.11.5.8; K&R II Sec. B3 p. 250; H&S
- > Sec. 15.7; PCS p. 178.
- ==========
- 15.2: I'm trying to do some simple trig, and I am #including <math.h>,
- but I keep getting "undefined: _sin" compilation errors.
-
- < A: Make sure you're linking against the correct math library. For
- ---
- > A: Make sure you're linking with the correct math library. For
- ==========
- > 15.4: How do I round numbers?
- >
- > A: The simplest and most straightforward way is with code like
- >
- > (int)(x + 0.5)
- >
- > This won't work properly for negative numbers, though.
- ==========
- > 15.5: How do I test for IEEE NaN and other special values?
- >
- > A: Many systems with high-quality IEEE floating-point
- > implementations provide facilities (e.g. an isnan() macro) to
- > deal with these values cleanly, and the Numerical C Extensions
- > Group (NCEG) is working to formally standardize such facilities.
- > A crude but usually effective test for NaN is exemplified by
- >
- > #define isnan(x) ((x) != (x))
- >
- > although non-IEEE-aware compilers may optimize the test away.
- ==========
- A: Contrary to popular belief and many people's wishes, this is not
- a C-related question. (Nor are closely-related questions
- concerning the echo of keyboard input.) The delivery of
- characters from a "keyboard" to a C program is a function of the
- operating system in use, and has not been standardized by the C
- language. Some versions of curses have a cbreak() function
- < which does what you want. Under UNIX, use ioctl to play with
- < the terminal driver modes (CBREAK or RAW under "classic"
- < versions; ICANON, c_cc[VMIN] and c_cc[VTIME] under System V or
- < Posix systems). Under MS-DOS, use getch(). Under VMS, try the
- < Screen Management (SMG$) routines, or curses, or issue low-level
- < $QIO's to ask for one character at a time. Under other
- ---
- > which does what you want. If you're specifically trying to read
- > a short password without echo, you might try getpass(). Under
- > Unix, use ioctl to play with the terminal driver modes (CBREAK
- > or RAW under "classic" versions; ICANON, c_cc[VMIN] and
- > c_cc[VTIME] under System V or Posix systems). Under MS-DOS, use
- > getch(). Under VMS, try the Screen Management (SMG$) routines,
- > or curses, or issue low-level $QIO's with the IO$_READVBLK (and
- > perhaps IO$M_NOECHO) function codes to ask for one character at
- > a time. Under other operating systems, you're on your own.
- ==========
- > 16.7: How can I check whether a file exists? I want to query the user
- > if a requested output file already exists.
- >
- > A: You can try the access() routine, although it's got a few
- > problems. (It isn't atomic with respect to the following
- > action, and it has anomalies if the program calling it is
- > running as root.)
- ==========
- 16.8: How can I find out the size of a file, prior to reading it in?
- ...
- > files). Some systems provide routines called filesize or
- > filelength.
- ==========
- > 16.12: How can I invoke an operating system command from within a
- > program?
- >
- > A: Use system().
- >
- > References: K&R II Sec. B6 p. 253; ANSI Sec. 4.10.4.5; H&S
- > Sec. 21.2; PCS Sec. 11 p. 179;
- ==========
- > 16.15: How can I do serial ("comm") port I/O?
- >
- > A: It's system-dependent. Under Unix, you typically open, read,
- > and write a device in /dev, and use the facilities of the
- > terminal driver to adjust its characteristics. Under MS-DOS,
- > you can either use some primitive BIOS interrupts, or (if you
- > require decent performance) one of any number of interrupt-
- > driven serial I/O packages.
- ==========
- 17.1: What can I safely assume about the initial values of variables
- which are not explicitly initialized?
- ...
- A: Variables with "static" duration (that is, those declared
- outside of functions, and those declared with the storage class
- < static), are guaranteed initialized to zero, as if the
- < programmer had typed "= 0". Therefore, such variables are
- ---
- > static), are guaranteed initialized (just once, at program
- > startup) to zero, as if the programmer had typed "= 0".
- ==========
- > 17.2: This code, straight out of a book, isn't compiling:
- >
- > f()
- > {
- > char a[] = "Hello, world!";
- > }
- >
- > A: Perhaps you have a pre-ANSI compiler, which doesn't allow
- > initialization of "automatic aggregates" (i.e. non-static local
- > arrays and structures). As a workaround, you can make the array
- > global or static. (You can always initialize local char *
- > variables with string literals, but see question 17.20). See
- > also questions 5.16 and 5.17.
- ==========
- > 17.4: How can I delete a line (or record) from the middle of a file?
- >
- > A: Short of rewriting the file, you probably can't. See also
- > question 16.9.
- ==========
- > 17.10: Is C++ a superset of C? Can I use a C++ compiler to compile C
- > code?
-
- > A: C++ was derived from C, and is largely based on it, but there
- > are some legal C constructs which are not legal C++. (Many C
- > programs will nevertheless compile correctly in a C++
- > environment.)
- ==========
- > 17.11: I need: A: Look for programs (see also
- > question 17.12) named:
- >
- > a C cross-reference cflow, calls, cscope
- > generator
- >
- > a C beautifier/pretty- cb, indent
- > printer
- ==========
- and/or uucp from a central, public-spirited site, such as uunet
- (ftp.uu.net, 192.48.96.9). However, this article cannot track
- or list all of the available archive sites and how to access
- < them. The comp.archives newsgroup contains numerous
- ---
- > them.
- >
- > Ajay Shah maintains an index of free numerical software; it is
- > posted periodically, and available where this FAQ list is
- > archived (see question 17.33). The comp.archives newsgroup
- ==========
- < 17.10: Why don't C comments nest? Are they legal inside quoted
- strings?
- ---
- > 17.14: Why don't C comments nest? How am I supposed to comment out
- > code containing comments? Are comments legal inside quoted
- strings?
-
- A: Nested comments would cause more harm than good, mostly because
- of the possibility of accidentally leaving comments unclosed by
- including the characters "/*" within them. For this reason, it
- is usually better to "comment out" large sections of code, which
- might contain comments, with #ifdef or #if 0 (but see question
- ==========
- > 17.15: How can I get the ASCII value corresponding to a character, or
- > vice versa?
- >
- > A: In C, characters are represented by small integers corresponding
- > to their values (in the machine's character set) so you don't
- > need a conversion routine: if you have the character, you have
- > its value.
- ==========
- > 17.20: Why does this code:
- >
- > char *p = "Hello, world!";
- > p[0] = tolower(p[0]);
- >
- > crash?
- >
- > A: String literals are not necessarily modifiable, except (in
- > effect) when they are used as array initializers. Try
- >
- > char a[] = "Hello, world!";
- >
- > (For compiling old code, some compilers have a switch
- > controlling whether strings are writable or not.) See also
- > questions 2.1, 2.2, 2.8, and 17.2.
- >
- > References: ANSI Sec. 3.1.4 .
- ==========
- 17.22: What do "Segmentation violation" and "Bus error" mean?
-
- A: These generally mean that your program tried to access memory it
- shouldn't have, invariably as a result of improper pointer use,
- < often involving malloc (see question 17.17) or perhaps scanf
- < (see question 11.2).
- ---
- > often involving uninitialized or improperly allocated pointers
- > (see questions 3.1 and 3.2), or malloc (see question 17.23), or
- > perhaps scanf (see question 11.2).
- ==========
- A number of debugging packages exist to help track down malloc
- < problems; one popular one is Conor P. Cahill's "dbmalloc".
- ---
- > problems; one popular one is Conor P. Cahill's "dbmalloc,"
- > posted to comp.sources.misc in September of 1992. Others are
- > "leak," available in volume 27 of the comp.sources.unix
- > archives; JMalloc.c and JMalloc.h in Fidonet's C_ECHO Snippets
- > (or ask archie; see question 17.12); and MEMDEBUG from
- > dorado.crpht.lu in pub/sources/memdebug . See also question
- > 17.12.
- ==========
- 17.24: Does anyone have a C compiler test suite I can use?
-
- < A: Plum Hall (1 Spruce Ave., Cardiff, NJ 08232, USA) sells one.
- ---
- > A: Plum Hall (formerly in Cardiff, NJ; now in Hawaii) sells one.
- ==========
- < compilers. Kahan's paranoia test, found in netlib on
- < research.att.com, strenuously tests a C implementation's
- < floating point capabilities.
- ---
- > compilers. Kahan's paranoia test, found in netlib/paranoia on
- > netlib.att.com, strenuously tests a C implementation's floating
- > point capabilities.
- ==========
- 17.25: Where can I get a YACC grammar for C?
-
- A: The definitive grammar is of course the one in the ANSI
- < standard. Several copies are floating around; keep your eyes
- < open. There is one (due to Jeff Lee) on uunet (see question
- < 17.8) in usenet/net.sources/ansi.c.grammar.Z (including a
- < companion lexer). Another one, by Jim Roskind, is in
- < pub/*grammar* at ics.uci.edu . The FSF's GNU C compiler
- ---
- A: The definitive grammar is of course the one in the ANSI
- > standard. Another grammar, by Jim Roskind, is in pub/*grammar*
- > at ics.uci.edu . A fleshed-out, working instance of the ANSI
- > grammar (due to Jeff Lee) is on uunet (see question 17.12) in
- > usenet/net.sources/ansi.c.grammar.Z (including a companion
- > lexer). The FSF's GNU C compiler contains a grammar, as does
- > the appendix to K&R II.
- ==========
- > 17.26: I need code to parse and evaluate expressions.
- >
- > A: Two available packages are "defunc," posted to comp.source.misc
- > in December, 1993 (V41 i32,33), to alt.sources in January, 1994,
- > and available from sunsite.unc.edu in
- > pub/packages/development/libraries/defunc-1.3.tar.Z; and
- > "parse," at lamont.ldgo.columbia.edu.
- ==========
- > 17.27: I need a sort of an "approximate" strcmp routine, for comparing
- > two strings for close, but not necessarily exact, equality.
- >
- > A: The traditional routine for doing this sort of thing involves
- > the "soundex" algorithm, which maps similar-sounding words to
- > the same numeric codes. Soundex is described in the Searching
- > and Sorting volume of Donald Knuth's classic _The Art of
- > Computer Programming_.
- ==========
- > 17.28: How can I find the day of the week given the date?
- >
- > A: Use mktime (see questions 12.6 and 12.7), or Zeller's
- > congruence. Here is one quick implementation posted by Tomohiko
- > Sakamoto:
- >
- > dayofweek(y, m, d) /* 0 = Sunday */
- > int y, m, d; /* 1 <= m <= 12, y > 1752 or so */
- > {
- > static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
- > y -= m < 3;
- > return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
- > }
- ==========
- > 17.29: Will 2000 be a leap year? Is (year % 4 == 0) an accurate test
- > for leap years?
- >
- > A: Yes and no, respectively. The full expression for the Gregorian
- > calendar is
- >
- > year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
- >
- > See a good astronomical almanac or other reference for details.
- ==========
- > 17.32: Are there any C tutorials on the net?
- >
- > A: There are at least two of them:
- >
- > "Notes for C programmers," by Christopher Sawtell,
- > available from:
- > svr-ftp.eng.cam.ac.uk:misc/sawtell_C.shar
- > garbo.uwasa.fi:/pc/c/c-lesson.zip
- > oak.oakland.edu:pub/msdos/c/LEARN-C.ZIP
- > paris7.jussieu.fr:/contributions/docs
- >
- > Tim Love's "C for Programmers,"
- > available from svr-ftp.eng.cam.ac.uk in the misc directory.
- ==========
- 17.33: Where can I get extra copies of this list? What about back
- issues?
-
- A: For now, just pull it off the net; it is normally posted to
- < comp.lang.c on the first of each month, with an Expiration: line
- < which should keep it around all month. It can also be found in
- < the newsgroups comp.answers and news.answers . Several sites
- < archive news.answers postings and other FAQ lists, including
- < this one: two sites are rtfm.mit.edu (directory pub/usenet), and
- < ftp.uu.net (directory usenet). The archie server should help
- < you find others. See the meta-FAQ list in news.answers for more
- < information; see also question 17.8.
- ---
- A: For now, just pull it off the net; it is normally posted to
- > comp.lang.c on the first of each month, with an Expires: line
- > which should keep it around all month. An abridged version is
- > also available (and posted), as is a list of changes
- > accompanying each significantly updated version. These lists
- > can also be found in the newsgroups comp.answers and
- > news.answers . Several sites archive news.answers postings and
- > other FAQ lists, including this one: two sites are rtfm.mit.edu
- > (directories pub/usenet/news.answers/C-faq/ and
- > pub/usenet/comp.lang.c/ ) and ftp.uu.net (directory
- > usenet/news.answers/C-faq/ ). The archie server should help you
- > find others; query it for "prog C-faq". See the meta-FAQ list
- > in news.answers for more information; see also question 17.12.
- ==========
- Acknowledgements
-
- Thanks to Jamshid Afshar, Sudheer Apte, Randall Atkinson, Dan Bernstein,
- Vincent Broman, Stan Brown, Joe Buehler, Gordon Burditt, Burkhard Burow,
- > Conor P. Cahill, D'Arcy J.M. Cain, Christopher Calabrese, Ian Cargill,
- > Paul Carter, Raymond Chen, Jonathan Coxhead, Lee Crawford, Steve Dahmer,
- > Andrew Daviel, James Davies, Jutta Degener, Norm Diamond, Jeff Dunlop,
- > Ray Dunn, Stephen M. Dunn, Michael J. Eager, Dave Eisen, Bjorn Engsig,
- > Chris Flatters, Rod Flores, Alexander Forst, Jeff Francis, Dave
- Gillespie, Samuel Goldstein, Alasdair Grant, Ron Guilmette, Doug Gwyn,
- > Tony Hansen, Joe Harrington, Guy Harris, Elliotte Rusty Harold, Jos
- > Horsmeier, Blair Houghton, Ke Jin, Kirk Johnson, Larry Jones, Kin-ichi
- > Kitano, Peter Klausler, Andrew Koenig, Tom Koenig, Ajoy Krishnan T,
- > Markus Kuhn, John Lauro, Felix Lee, Mike Lee, Timothy J. Lee, Tony Lee,
- > Don Libes, Christopher Lott, Tim Love, Tim McDaniel, Stuart MacMartin,
- > John R. MacMillan, Bob Makowski, Evan Manning, Barry Margolin, George
- > Matas, Brad Mears, Bill Mitchell, Mark Moraes, Darren Morby, Ken Nakata,
- > Landon Curt Noll, David O'Brien, Richard A. O'Keefe, Hans Olsson, Philip
- > (lijnzaad@embl-heidelberg.de), Christopher Phillips, Francois Pinard,
- > Dan Pop, Kevin D. Quitt, Pat Rankin, J. M. Rosenstock, Erkki Ruohtula,
- > Tomohiko Sakamoto, Rich Salz, Chip Salzenberg, Paul Sand, DaviD
- > W. Sanderson, Christopher Sawtell, Paul Schlyter, Doug Schmidt, Rene
- > Schmit, Patricia Shanahan, Peter da Silva, Joshua Simons, Henry Spencer,
- > David Spuler, Melanie Summit, Erik Talvola, Clarke Thatcher, Wayne
- > Throop, Chris Torek, Andrew Tucker, Goran Uddeborg, Rodrigo Vanegas, Jim
- > Van Zandt, Wietse Venema, Ed Vielmetti, Larry Virden, Chris Volpe, Mark
- > Warren, Larry Weiss, Freek Wiedijk, Lars Wirzenius, Dave Wolverton,
- Mitch Wright, Conway Yee, and Zhuo Zang, who have contributed, directly
- or indirectly, to this article. Special thanks to Karl Heuer, and
- particularly to Mark Brader, who (to borrow a line from Steve Johnson)
- have goaded me beyond my inclination, and occasionally beyond my
- endurance, in relentless pursuit of a better FAQ list.
- ==========
- < This article is Copyright 1988, 1990-1993 by Steve Summit.
- ---
- > This article is Copyright 1988, 1990-1994 by Steve Summit.
- ==========
-
- Steve Summit
- scs@eskimo.com
-